package com.happy3w.ssp.schoolmatehome.service.user;

import com.happy3w.java.ext.StringUtils;
import com.happy3w.ssp.schoolmatehome.entity.User;
import com.happy3w.ssp.schoolmatehome.exception.MessageException;
import com.happy3w.ssp.schoolmatehome.repository.FollowRepository;
import com.happy3w.ssp.schoolmatehome.repository.UserRepository;
import com.happy3w.ssp.schoolmatehome.repository.UserStateRepository;
import com.happy3w.ssp.schoolmatehome.service.auth.RegUserDto;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.Optional;
import java.util.UUID;

@RequiredArgsConstructor
@Service
public class UserService {

    private final UserRepository userRepository;
    private final UserStateRepository userStateRepository;
    private final FollowRepository followRepository;
    private final PasswordEncoder passwordEncoder;

    public UserInfo createUser(RegUserDto user) {
        if (StringUtils.hasText(user.getPhone())
                && userRepository.findByPhone(user.getPhone()).isPresent()) {
            throw new MessageException("用户已存在: " + user.getPhone());
        }
        if (!StringUtils.hasText(user.getPhone())) {
            user.setPhone(null);
        }
        if (StringUtils.hasText(user.getEmail())
                && userRepository.findByEmail(user.getEmail()).isPresent()) {
            throw new MessageException("用户已存在: " + user.getEmail());
        }
        if (!StringUtils.hasText(user.getEmail())) {
            user.setEmail(null);
        }
        String salt = UUID.randomUUID().toString();
        String passwordHash = passwordEncoder.encode(user.getPassword() + salt);
        User newUser = userRepository.save(User.builder()
                .name(user.getName())
                .phone(user.getPhone())
                .email(user.getEmail())
                .passwordHash(passwordHash)
                .salt(salt)
                .createdAt(new Date())
                .updatedAt(new Date())
                .build());
        return UserInfo.from(newUser);
    }

    public User getUserByWxUnionId(String wxUnionId) {
        return userRepository.findByWxUnionId(wxUnionId)
                .orElseThrow(() -> new MessageException("User not found with wxUnionId: " + wxUnionId));
    }

    public Optional<User> getUserById(Long id) {
        return userRepository.findById(id);
    }

    public Optional<UserSummary> getUserStateById(Long id, User curUser) {
        return userRepository.findById(id)
                .map(user -> {
                    UserStateSummary state = userStateRepository.findById(user.getId());
                    boolean isFollowed = followRepository.isFollowed(user.getId(), curUser.getId());
                    return UserSummary.builder()
                            .id(user.getId())
                            .name(user.getName())
                            .avatar(user.getAvatar())
                            .state(state)
                            .isFollowed(isFollowed)
                            .build();
                });
    }

    public User updateName(Long id, String name) {
        User existUser = userRepository.findById(id)
                .orElseThrow(() -> new MessageException("User not found with id: " + id));
        existUser.setName(name);
        userRepository.save(existUser);
        return existUser;
    }

    public void markFollow(Long userId, User user) {
        followRepository.markFollow(userId, user.getId());
    }

    public void unmarkFollow(Long userId, User user) {
        followRepository.unmarkFollow(userId, user.getId());
    }

}
